#include<iostream>
#include<vector>
#include<queue>
#include<malloc.h>
#include <math.h>

void multigrid_one(double *f,int RO,int IO,double *au,double RA,int ncycle_M,int n,double *ig,int cycletype,double *y);


//n为区间个数加一！！！cycletype为0代表用V_cycle，为1代表用FMG_cycle;RO为0代表选full-weighting，为1代表injection;IO为0代表linear，为1代表quadratic。
//还可以更改的量有:RA为相对精度,ncycle_M为最大迭代次数,f为右侧函数表达式,ig为初始向量.

int main()
{
  int i,n,cycletype,RO,IO,ic,ncycle_M,csn,csr,csi,csc;
  double *f,h,*x,*ig,*au,RA,*y;

  std::cout<<"N is the number of intervals plus one!!! Cycletype 0 means V Cycle, 1 represents FMG Cycle; RO = 0 means full-weight, 1 for injection; IO = 0 for linear, 1 for Quadric."<<std::endl;

   
  
  //第三题
  for (csn=7;csn<=10;csn++){
    n=pow(2.0,csn)+1;
    for (csr=0;csr<=1;csr++){
      RO=csr;
      for (csi=0;csi<=1;csi++){
	IO=csi;
	for (csc=0;csc<=1;csc++){
	  cycletype=csc;
	  std::cout<<"n="<<n<<",RO="<<RO<<",IO="<<IO<<",cycletype="<<cycletype<<std::endl;

  
  h=1.0/(n-1);
    x=(double *)malloc(sizeof(double)*2000);
    y=(double *)malloc(sizeof(double)*2000);
    ig=(double *)malloc(sizeof(double)*2000);
    au=(double *)malloc(sizeof(double)*2000);
   ncycle_M=100;RA=1e-8;
     
  //计算右侧向量
  f=(double *)malloc(sizeof(double)*2000);
  for (i=1;i<=n;i++){
    x[i]=h*(i-1);
    y[i]=exp(sin(x[i]));
    f[i]=cos(x[i])*cos(x[i])*exp(sin(x[i]))-sin(x[i])*exp(sin(x[i]));
  }
  ig[1]=1;ig[n]=exp(sin(1));
   au[1]=1;au[n]=exp(sin(1));

  
  multigrid_one(f,RO,IO,au,RA,ncycle_M,n,ig,cycletype,y);


  //输出解au
  //for (ic=1;ic<=n;ic++){
  //  std::cout<<au[ic]<<std::endl;
  //  }
   
  	}
      }
    }
  }
  
  //第四题
  std::cout<<" "<<std::endl;
   std::cout<<" "<<std::endl;
    std::cout<<" "<<std::endl;
     std::cout<<" "<<std::endl;
  std::cout<<"In the fourth question,we choose n=1025,injection,quadratic and FMG cycle:"<<std::endl;
    n=1025;RO=1;IO=1;cycletype=1;
  h=1.0/(n-1);
    x=(double *)malloc(sizeof(double)*2000);
    y=(double *)malloc(sizeof(double)*2000);
    ig=(double *)malloc(sizeof(double)*2000);
    au=(double *)malloc(sizeof(double)*2000);
   ncycle_M=30;RA=2.2e-16;
   
  //计算右侧向量
  f=(double *)malloc(sizeof(double)*2000);
  for (i=1;i<=n;i++){
    x[i]=h*(i-1);
    y[i]=exp(sin(x[i]));
    f[i]=cos(x[i])*cos(x[i])*exp(sin(x[i]))-sin(x[i])*exp(sin(x[i]));
  }
  ig[1]=1;ig[n]=exp(sin(1));
   au[1]=1;au[n]=exp(sin(1));

  
   multigrid_one(f,RO,IO,au,RA,ncycle_M,n,ig,cycletype,y);

  
  //第五题:选取u(x)=sinx*sin(1-x).
  std::cout<<" "<<std::endl;
   std::cout<<" "<<std::endl;
    std::cout<<" "<<std::endl;
     std::cout<<" "<<std::endl;
  std::cout<<"In question five,we choose u(x)=sinx*sin(1-x).:"<<std::endl;
   for (csn=7;csn<=10;csn++){
    n=pow(2.0,csn)+1;
    for (csr=0;csr<=1;csr++){
      RO=csr;
      for (csi=0;csi<=1;csi++){
	IO=csi;
	for (csc=0;csc<=1;csc++){
	  cycletype=csc;
	  std::cout<<"n="<<n<<",RO="<<RO<<",IO="<<IO<<",cycletype="<<cycletype<<std::endl;
  
  h=1.0/(n-1);
    x=(double *)malloc(sizeof(double)*2000);
    y=(double *)malloc(sizeof(double)*2000);
    ig=(double *)malloc(sizeof(double)*2000);
    au=(double *)malloc(sizeof(double)*2000);
   ncycle_M=100;RA=1e-8;
   
  //计算右侧向量
  f=(double *)malloc(sizeof(double)*2000);
  for (i=1;i<=n;i++){
    x[i]=h*(i-1);
    y[i]=sin(x[i])*sin(1-x[i]);
    f[i]=-2*sin(x[i])*sin(1-x[i])-2*cos(x[i])*cos(1-x[i]);
  }
  ig[1]=0;ig[n]=0;
   au[1]=0;au[n]=0;

  
   multigrid_one(f,RO,IO,au,RA,ncycle_M,n,ig,cycletype,y);


   
  	}
      }
    }
    }
  
  

}

  
  
